﻿using SharpML.Api.Enumerations;
using SharpML.Api.Extensions;
using SharpML.Api.Interfaces;
using SharpML.Api.Types;
using System.Configuration;

namespace SharpML.Api.Abstraction
{
    public abstract class PluginComponent : IPluginComponent
    {
        #region - Private Member Variables -

            /// <summary>
            /// Backed because accessor strictly controls casing
            /// </summary>
            private string name;

        #endregion

        #region - Construction -

            public PluginComponent()
            {
                // As a default, set the name from the description attribute or the class name itself
                name = this.GetType().GetDescriptionFromAttribute() ?? this.GetType().Name;
            }

        #endregion

        #region - Public Abstract Properties -

            /// <summary>
            /// Concrete or abstract implementation should set the classification to make less code for other derivers
            /// </summary>
            public abstract PluginComponentType Classification { get; }

        #endregion

        #region - Public Properties -

            public string Name // { get; protected set; }
            {
                get { return name; }
                protected set { name = value.ProperCase(); }
            }

        #endregion

        #region - Public Functionality -

            /// <summary>
            /// The proper design was to have name read-only from external classes, so this was needed
            /// </summary>
            /// <param name="newName"></param>
            public void SetName( string newName )
            {
                name = newName.ProperCase();
            }

        #endregion

        #region - Abstract IFlowControl Implemenation -

            /// <summary>
            /// Return a UserControl marked with the <see cref="IPluginConfiguration"/> interface.
            /// </summary>
            public abstract IPluginConfiguration Gui { get; }

            /// <summary>
            /// Override and return some serialized object.  All values will be stored in the active configuration and set upon load / config change.
            /// You can use the api extension classes to serialize Properties.Settings, but settings are available for every plugin component, so
            /// take care not the same thing multiple times per plugin assembly.
            /// </summary>
            public virtual XmlSerializableDictionary<string,object> Settings 
            { 
                get { return null; }
                set { }
            }

        #endregion

        #region - Base Class Overrides -

            public override string ToString()
            {
                var type = GetType();
                return type.GetDescriptionFromAttribute( "Unnamed Plugin: " + type.Name );
            }

        #endregion
    }
}
